from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
import sys, types
import osg

import pyglui
from pyglui.desktop import getRenderer, getDesktop

gwin_id = 0
mgr = None     # Scene manager
md = None      # Global handle to desktop


class MyDesktop:
   def __init__(self, local_dict):
      self.locals = local_dict
      
      fmenu = pyglui.widgets.Menu("File", name="FileMenu")
      fmenu.addItem("Load", self.onLoad)
      fmenu.addItem("Exit", self.onExit)
      
      vmenu = pyglui.widgets.Menu("Views", name="ViewsMenu")
      vmenu.addItem("Console", self.onCreateConsole)
      vmenu.addItem("Viewer", self.onCreateViewer)      
      vmenu.addItem("Tree Viewer", self.onCreateTreeViewer)      
      
      self.mbar = pyglui.widgets.MenuBar(name="MenuBar")
      self.mbar.addMenu(fmenu)
      self.mbar.addMenu(vmenu)
      
      w = pyglui.frame.Frame(25,25,200,100, "Control Window")
      self.posStatusLabel = pyglui.widgets.Label("Nothing")
      self.hitStatusLabel = pyglui.widgets.Label("Nothing")
      self.btnStatusLabel = pyglui.widgets.Label("Nothing")
      w.addChild(self.posStatusLabel)
      w.addChild(self.hitStatusLabel, pyglui.layouts.FlowLayoutManager.NEWLINE)
      w.addChild(self.btnStatusLabel, pyglui.layouts.FlowLayoutManager.NEWLINE)
      #w.addChild(pyglui.widgets.Button("Add Win", self.onButton), pyglui.layouts.FlowLayoutManager.NEWLINE)
      w.pack()
        
   
   def updateGUI(self):
      mouse_pos = pyglui.desktop.getRenderer().getMousePosition()
      pos_text = "pos: %s, %s  "%(mouse_pos[0], mouse_pos[1])
      self.posStatusLabel.setText(pos_text)
      over_window = getRenderer().cursorOverWindow
      hit_it = pyglui.desktop.getDesktop().checkHit(mouse_pos[0], mouse_pos[1])
      hit_distance = pyglui.desktop.getDesktop().checkHitDistance(mouse_pos[0], mouse_pos[1])
      hit_text = "Over:%s Hit:%s  dist:%s"%(over_window, hit_it,hit_distance)
      self.hitStatusLabel.setText(hit_text)
      self.btnStatusLabel.setText(str(getRenderer().curMouseButtons))

   def onCreateConsole(self, mitem):
      self.console = pyglui.console.Console(100,100,300,200, locals=self.locals)

   def onCreateViewer(self, mitem):
      self.viewer = pyglui.viewer.Viewer(200, 200, self.locals)
   
   def onCreateTreeViewer(self, mitem):
      self.tree_viewer = pyglui.viewer.TreeViewerWindow(200,200,200,300,self.locals)
      
   def onExit(self, mitem):
      sys.exit(0)

   def onLoad(self, mitem):
      print "Not implemented yet."


def display():
   global mgr, md
   mgr.idle()
   mgr.redraw()
   getRenderer().runMe()
   md.updateGUI()
   glutSwapBuffers()
   

def reshape(w, h):
   getRenderer().ReSizeGLScene(w,h)
   
   mgr.resize(w,h)
   glutPostRedisplay()
   
def mouse(button, state, x, y):
   print "Mouse: ", (button,state,x,y)
   if getRenderer().onMouse(button,state,x,y):
      return
   
   if (state == GLUT_DOWN):
      mgr.mouseButtonPress(button, x, y)
   else:
      mgr.mouseButtonRelease(button, x, y)
      
   glutPostRedisplay()

def motion(x, y):
   print "Motion: ", (x,y)
   if getRenderer().onMotion(x,y):
      return

   mgr.mouseMove(x,y)
   glutPostRedisplay()

def keyboard(key,x,y):
   if getRenderer().onKeyDown(key,x,y):
      return
         
   print "Key: ", key, "  ", (x,y)
   if key == chr(27):
       osg.osgExit()
       sys.exit(0)

def initGL():
   glClearDepth (1.0)
   glEnable (GL_DEPTH_TEST)
   glClearColor (0.0, 0.0, 0.0, 0.0)
   glShadeModel (GL_SMOOTH)
   print "Allocating several thousand display lists to keep OpenSG happy...."
   glGenLists(10000)

def setupGLUTandPyGlui():
   glutInit(sys.argv)
   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
   glutInitWindowSize(800, 600)
   #glutInitWindowPosition(100, 100)

   gwin_id = glutCreateWindow('pyOpenSG')

   glutReshapeFunc(reshape)
   glutDisplayFunc(display)
   glutIdleFunc(display)
   glutMouseFunc(mouse)
   glutMotionFunc(motion)
   glutKeyboardFunc(keyboard)

   # Setup the pyglui system
   pyglui.init(800,600,renderer="glut_base")
   
   r = getRenderer()
   
   glutPassiveMotionFunc(r.onMotion)
   glutKeyboardUpFunc(r.onKeyUp)
   glutSpecialFunc(r.onSpecialDown)
   glutSpecialUpFunc(r.onSpecialUp) 
      
   initGL()  
  
   return gwin_id


# ---- Main --- #
def main():
   global mgr, md
   print "argv: ", sys.argv
   osg.osgInit(0,[])

   win_id = setupGLUTandPyGlui()
   #initGL()
   #gwin = osg.GLUTWindow.create()
   #gwin.setId(win_id)
   gwin = osg.PassiveWindow.create()
   gwin.init()

   mgr = osg.SimpleSceneManager()

   sfh = osg.SceneFileHandler.the()
   
   if len(sys.argv) < 2:
      print "Loading torus...."
      scene = osg.RefPtr(osg.makeTorus(0.5,2,16,16))
   else:
      scene = osg.RefPtr(sfh.read(sys.argv[1]))

   node = sfh.read("d.osb")
   #scene.addChild(node)
   #scene = node
   
   
   # import more stuff into locals

   local_name_space = locals().copy()
   local_name_space["osg"] = osg   
   import OpenGL.GL as GL
   local_name_space["GL"] = GL
   local_name_space["mgr"] = mgr
   md = MyDesktop(local_name_space)   
   
   print "Locals: ", locals()
   print "Globals: ", globals()

   mgr.setWindow(gwin)
   mgr.setRoot(scene)
   mgr.showAll()
   mgr.setStatistics(True)

   glutMainLoop()


# Start application
main()


